﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace SafeLoad.NControl
{
    /// <summary>
    /// NPipeLineFour.xaml 的交互逻辑
    /// </summary>
    public partial class NPipeLineFour : UserControl
    {
        public NPipeLineFour()
        {
            InitializeComponent();

			//offect1DoubleAnimation = new DoubleAnimation(0, 10, TimeSpan.FromMilliseconds(1000));
			//offect1DoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
			//BeginAnimation(LineOffect1Property, offect1DoubleAnimation);

			//offect2DoubleAnimation = new DoubleAnimation(0, 10, TimeSpan.FromMilliseconds(1000));
			//offect2DoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
			//BeginAnimation(LineOffect2Property, offect2DoubleAnimation);

			//offect3DoubleAnimation = new DoubleAnimation(0, 10, TimeSpan.FromMilliseconds(1000));
			//offect3DoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
			//BeginAnimation(LineOffect3Property, offect3DoubleAnimation);

			//offect4DoubleAnimation = new DoubleAnimation(0, 10, TimeSpan.FromMilliseconds(1000));
			//offect4DoubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
			//BeginAnimation(LineOffect4Property, offect3DoubleAnimation);
		}
        public static void PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
        {
            NPipeLineFour pipeLine = (NPipeLineFour)dependency;
            pipeLine.UpdatePath();
        }

        public static readonly DependencyProperty PipeWidthProperty =
          DependencyProperty.Register("PipeWidth", typeof(int), typeof(NPipeLineFour),
            new PropertyMetadata(30, new PropertyChangedCallback(PropertyChangedCallback)));
        public int PipeWidth
        {
            get { return (int)GetValue(PipeWidthProperty); }
            set { SetValue(PipeWidthProperty, value); }
        }

        public Color EdgeColor
        {
            get { return (Color)GetValue(EdgeColorProperty); }
            set { SetValue(EdgeColorProperty, value); }
        }
        public static readonly DependencyProperty EdgeColorProperty =
            DependencyProperty.Register("EdgeColor", typeof(Color), typeof(NPipeLineFour), new PropertyMetadata(Colors.LightGray));

        public Color CenterColor
        {
            get { return (Color)GetValue(CenterColorProperty); }
            set { SetValue(CenterColorProperty, value); }
        }
        public static readonly DependencyProperty CenterColorProperty =
            DependencyProperty.Register("CenterColor", typeof(Color), typeof(NPipeLineFour), new PropertyMetadata(Colors.LightGray));

		public static void MoveSpeed1PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
        {
			NPipeLineFour pipeFour = (NPipeLineFour)dependency;
			pipeFour.MoveSpeedOrActiveChanged1();
		}
		public static void MoveSpeed2PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineFour pipeFour = (NPipeLineFour)dependency;
			pipeFour.MoveSpeedOrActiveChanged2();
		}
		public static void MoveSpeed3PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineFour pipeFour = (NPipeLineFour)dependency;
			pipeFour.MoveSpeedOrActiveChanged3();
		}
		public static void MoveSpeed4PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineFour pipeFour = (NPipeLineFour)dependency;
			pipeFour.MoveSpeedOrActiveChanged4();
		}

		private void MoveSpeedOrActiveChanged1()
        {
			MoveSpeedOrActiveChanged(PipeLineActive1, MoveSpeed1, ref offect1DoubleAnimation, LineOffect1Property);
		}
		private void MoveSpeedOrActiveChanged2()
		{
			MoveSpeedOrActiveChanged(PipeLineActive2, MoveSpeed2, ref offect2DoubleAnimation, LineOffect2Property);
		}
		private void MoveSpeedOrActiveChanged3()
		{
			MoveSpeedOrActiveChanged(PipeLineActive3, MoveSpeed3, ref offect3DoubleAnimation, LineOffect3Property);
		}
		private void MoveSpeedOrActiveChanged4()
		{
			MoveSpeedOrActiveChanged(PipeLineActive4, MoveSpeed4, ref offect4DoubleAnimation, LineOffect4Property);
		}

		private void MoveSpeedOrActiveChanged(bool lineActive, double moveSpeed,
			ref DoubleAnimation animation, DependencyProperty offectProperty)
		{
			if (!lineActive)
			{
				//取消动画
				if (animation != null)
				{
					BeginAnimation(offectProperty, null);
					animation = null;
				}
				return;
			}

			if (Math.Abs(moveSpeed) < 0.001)
			{
				//moveSpeed等于0， 停止动画
				if (animation != null)
				{
					BeginAnimation(offectProperty, null);
					animation = null;
				}
			}
			else if (moveSpeed > 0)
			{
				animation = new DoubleAnimation(0d, 10d, TimeSpan.FromMilliseconds(300 / Math.Abs(moveSpeed)));
				animation.RepeatBehavior = RepeatBehavior.Forever;
				BeginAnimation(offectProperty, animation);
			}
			else
			{
				animation = new DoubleAnimation(0d, -10d, TimeSpan.FromMilliseconds(300 / Math.Abs(moveSpeed)));
				animation.RepeatBehavior = RepeatBehavior.Forever;
				BeginAnimation(offectProperty, animation);
			}
		}

		/// <summary>
		/// 获取或设置管道1号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive1
		{
			get { return (bool)GetValue(PipeLineActive1Property); }
			set { SetValue(PipeLineActive1Property, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineActive1.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineActive1Property =
			DependencyProperty.Register("PipeLineActive1", typeof(bool), typeof(NPipeLineFour), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed1PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道2号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive2
		{
			get { return (bool)GetValue(PipeLineActive2Property); }
			set { SetValue(PipeLineActive2Property, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineActive2.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineActive2Property =
			DependencyProperty.Register("PipeLineActive2", typeof(bool), typeof(NPipeLineFour), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed2PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道3号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive3
		{
			get { return (bool)GetValue(PipeLineActive3Property); }
			set { SetValue(PipeLineActive3Property, value); }
		}
		public static readonly DependencyProperty PipeLineActive3Property =
			DependencyProperty.Register("PipeLineActive3", typeof(bool), typeof(NPipeLineFour), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed3PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道4号线是否激活液体显示
		/// </summary>
		public bool PipeLineActive4
        {
            get { return (bool)GetValue(PipeLineActive4Property); }
            set { SetValue(PipeLineActive4Property, value); }
        }
		public static readonly DependencyProperty PipeLineActive4Property =
			DependencyProperty.Register("PipeLineActive4", typeof(bool), typeof(NPipeLineFour), 
				new PropertyMetadata(false, new PropertyChangedCallback(MoveSpeed4PropertyChangedCallback)));

		/// <summary>
		/// 获取或设置管道1号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed1
		{
			get { return (double)GetValue(MoveSpeed1Property); }
			set { SetValue(MoveSpeed1Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed1.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed1Property =
			DependencyProperty.Register("MoveSpeed1", typeof(double), typeof(NPipeLineFour),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed1PropertyChangedCallback)));

		//public static void MoveSpeed1PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		//{
		//	NPipeLineFour pipeLine = (NPipeLineFour)dependency;
		//	pipeLine.UpdateMoveSpeed(LineOffect1Property, pipeLine.offect1DoubleAnimation, pipeLine.MoveSpeed1);
		//}

		private DoubleAnimation offect1DoubleAnimation = null;

		//private void UpdateMoveSpeed(DependencyProperty property, DoubleAnimation animation, double speed)
		//{
		//	if (speed > 0.00001)
		//	{
		//		animation.From = 0d;
		//		animation.To = 10d;
		//		animation.Duration = TimeSpan.FromMilliseconds(300 / speed);
		//		BeginAnimation(property, animation);
		//	}
		//	else if (speed < -0.00001)
		//	{
		//		animation.From = 0d;
		//		animation.To = -10d;
		//		animation.Duration = TimeSpan.FromMilliseconds(300 / Math.Abs(speed));
		//		BeginAnimation(property, animation);
		//	}
		//	else
		//	{
		//		animation.From = 0d;
		//		animation.To = 0d;
		//		BeginAnimation(property, animation);
		//	}

		//}

		/// <summary>
		/// 获取或设置管道2号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed2
		{
			get { return (double)GetValue(MoveSpeed2Property); }
			set { SetValue(MoveSpeed2Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed2.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed2Property =
			DependencyProperty.Register("MoveSpeed2", typeof(double), typeof(NPipeLineFour),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed2PropertyChangedCallback)));

		//public static void MoveSpeed2PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		//{
		//	NPipeLineFour pipeLine = (NPipeLineFour)dependency;
		//	pipeLine.UpdateMoveSpeed(LineOffect2Property, pipeLine.offect2DoubleAnimation, pipeLine.MoveSpeed2);
		//}

		private DoubleAnimation offect2DoubleAnimation = null;


		/// <summary>
		/// 获取或设置管道3号线液体流动的速度，0为静止，正数为正向流动，负数为反向流动
		/// </summary>
		public double MoveSpeed3
		{
			get { return (double)GetValue(MoveSpeed3Property); }
			set { SetValue(MoveSpeed3Property, value); }
		}

		// Using a DependencyProperty as the backing store for MoveSpeed3.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty MoveSpeed3Property =
			DependencyProperty.Register("MoveSpeed3", typeof(double), typeof(NPipeLineFour),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed3PropertyChangedCallback)));

		//public static void MoveSpeed3PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		//{
		//	NPipeLineFour pipeLine = (NPipeLineFour)dependency;
		//	pipeLine.UpdateMoveSpeed(LineOffect3Property, pipeLine.offect3DoubleAnimation, pipeLine.MoveSpeed3);
		//}

		private DoubleAnimation offect3DoubleAnimation = null;

		public double MoveSpeed4
        {
            get { return (double)GetValue(MoveSpeed4Property); }
            set { SetValue(MoveSpeed4Property, value); }
        }
		public static readonly DependencyProperty MoveSpeed4Property =
			DependencyProperty.Register("MoveSpeed4", typeof(double), typeof(NPipeLineFour),
				new PropertyMetadata(0d, new PropertyChangedCallback(MoveSpeed4PropertyChangedCallback)));
		//public static void MoveSpeed4PropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		//{
		//	NPipeLineFour pipeLine = (NPipeLineFour)dependency;
		//	pipeLine.UpdateMoveSpeed(LineOffect4Property, pipeLine.offect4DoubleAnimation, pipeLine.MoveSpeed4);
		//}
		private DoubleAnimation offect4DoubleAnimation = null;


		/// <summary>
		/// 管道1的偏移
		/// </summary>
		public double LineOffect1
		{
			get { return (double)GetValue(LineOffect1Property); }
			set { SetValue(LineOffect1Property, value); }
		}
		public static readonly DependencyProperty LineOffect1Property =
			DependencyProperty.Register("LineOffect1", typeof(double), typeof(NPipeLineFour), new PropertyMetadata(0d));

		/// <summary>
		/// 管道2的偏移
		/// </summary>
		public double LineOffect2
		{
			get { return (double)GetValue(LineOffect2Property); }
			set { SetValue(LineOffect2Property, value); }
		}
		public static readonly DependencyProperty LineOffect2Property =
			DependencyProperty.Register("LineOffect2", typeof(double), typeof(NPipeLineFour), new PropertyMetadata(0d));

		/// <summary>
		/// 管道3的偏移
		/// </summary>
		public double LineOffect3
		{
			get { return (double)GetValue(LineOffect3Property); }
			set { SetValue(LineOffect3Property, value); }
		}
		public static readonly DependencyProperty LineOffect3Property =
			DependencyProperty.Register("LineOffect3", typeof(double), typeof(NPipeLineFour), new PropertyMetadata(0d));

		/// <summary>
		/// 管道4的偏移
		/// </summary>
		public double LineOffect4
        {
            get { return (double)GetValue(LineOffect4Property); }
            set { SetValue(LineOffect4Property, value); }
        }
		public static readonly DependencyProperty LineOffect4Property =
			DependencyProperty.Register("LineOffect4", typeof(double), typeof(NPipeLineFour), new PropertyMetadata(0d));

		/// <summary>
		/// 获取或设置中间管道线的宽度信息，默认为3
		/// </summary>
		public int PipeLineWidth
		{
			get { return (int)GetValue(PipeLineWidthProperty); }
			set { SetValue(PipeLineWidthProperty, value); }
		}

		// Using a DependencyProperty as the backing store for PipeLineWidth.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty PipeLineWidthProperty =
			DependencyProperty.Register("PipeLineWidth", typeof(int), typeof(NPipeLineFour), new PropertyMetadata(2));

		/// <summary>
		/// 获取或设置流动状态时管道控件的中心颜色
		/// </summary>
		public Color ActiveLineCenterColor
		{
			get { return (Color)GetValue(ActiveLineCenterColorProperty); }
			set { SetValue(ActiveLineCenterColorProperty, value); }
		}

		// Using a DependencyProperty as the backing store for ActiveLineCenterColor.  This enables animation, styling, binding, etc...
		public static readonly DependencyProperty ActiveLineCenterColorProperty =
			DependencyProperty.Register("ActiveLineCenterColor", typeof(Color), typeof(NPipeLineFour), new PropertyMetadata(Colors.DodgerBlue));

		public static void PipeWidthPropertyChangedCallback(DependencyObject dependency, DependencyPropertyChangedEventArgs e)
		{
			NPipeLineFour pipeLine = (NPipeLineFour)dependency;
			pipeLine.PipeWidthUpdate();
		}

		public void PipeWidthUpdate()
		{
			UpdatePath();
		}

		protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
        {
            base.OnRenderSizeChanged(sizeInfo);
            UpdatePath();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            UpdatePath();
        }

        public void UpdatePath()
        {
            /*
             ------p1_1-----p1_2------
            |                        |
            |                        |
            p2_1   p2_2     p2_3     p2_4
            |                        |
            |            p3          |
            |                        |
            p4_1   p4_2     p4_3     p4_4
            |                        |
            |                        |
            -------p5_1-----p5_2------
             */

            Point p1_1 = new Point((ActualWidth - PipeWidth) / 2d, 0);
            Point p1_2 = new Point(p1_1.X + PipeWidth, 0);
            Point p2_1 = new Point(0, (ActualHeight - PipeWidth) / 2d);
            Point p2_2 = new Point(p1_1.X, p2_1.Y);
            Point p2_3 = new Point(p1_2.X, p2_1.Y);
            Point p2_4 = new Point(ActualWidth, p2_1.Y);
            Point p3 = new Point(ActualWidth / 2, ActualHeight / 2);
            Point p4_1 = new Point(0, p2_1.Y + PipeWidth);
            Point p4_2 = new Point(p1_1.X, p4_1.Y);
            Point p4_3 = new Point(p1_2.X, p4_1.Y);
            Point p4_4 = new Point(ActualWidth, p4_1.Y);
            Point p5_1 = new Point(p1_1.X, ActualHeight);
            Point p5_2 = new Point(p1_2.X, ActualHeight);


            polygon1.Points = new PointCollection(new Point[] {
                    p1_1,p2_2,p3,p2_3,p1_2,p1_1
                });
            polygon2.Points = new PointCollection(new Point[] {
                    p2_4,p2_3,p3,p4_3,p4_4,p2_4
                });

            polygon3.Points = new PointCollection(new Point[] {
                    p5_2,p4_3,p3,p4_2,p5_1,p5_1
                });

            polygon4.Points = new PointCollection(new Point[] {
                    p4_1,p4_2,p3,p2_2,p2_1,p4_1
                });

			var g1 = new StreamGeometry();
			using (StreamGeometryContext context = g1.Open())
            {
				context.BeginFigure(new Point(ActualWidth / 2d, 0), false, false);
				context.LineTo(new Point(ActualWidth / 2d, ActualHeight / 2d), true, false);
			}
			path1.Data = g1;

			var g2 = new StreamGeometry();
			using(StreamGeometryContext context = g2.Open())
            {
				context.BeginFigure(new Point(ActualWidth, ActualHeight / 2d), false, false);
				context.LineTo(new Point(ActualWidth / 2d, ActualHeight / 2d), true, false);
			}
			path2.Data = g2;

			var g3 = new StreamGeometry();
			using(StreamGeometryContext context = g3.Open())
            {
				context.BeginFigure(new Point(ActualWidth / 2d, ActualHeight), false, false);
				context.LineTo(new Point(ActualWidth / 2d, ActualHeight / 2d), true, false);
			}
			path3.Data = g3;

			var g4 = new StreamGeometry();
			using (StreamGeometryContext context = g4.Open())
            {
				context.BeginFigure(new Point(0, ActualHeight / 2d), false, false);
				context.LineTo(new Point(ActualWidth / 2d, ActualHeight / 2d), true, false);
			}
			path4.Data = g4;
        }
    }
}
